package com.example.lxj.base.aspectj;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.example.lxj.base.utils.JWTUtils;
import com.example.lxj.system.entity.SysUserToken;
import com.example.lxj.system.service.ISysUserTokenService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.example.lxj.base.config.JWTConfig;

import jakarta.servlet.http.HttpServletRequest;

/**
 * 不需要登录的切面
 */
@Aspect
@Component
@Order(1)
public class NoNeedLoginAspect {

    @Autowired
    private JWTConfig jwtConfig;

    @Autowired
    private ISysUserTokenService sysUserTokenService;

    /**
     * 免登陆校验
     *
     * @param joinPoint
     * @return
     * @throws Throwable
     * @description 切面将作用于所有标注了@RestController注解的类的所有方法，但排除了那些标注了NoNeedLogin注解的方法。
     */
    @Around("@within(org.springframework.web.bind.annotation.RestController) && execution(* *(..)) && !@annotation(com.example.lxj.base.annoation.NoNeedLogin)")
    public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
        // 获取request对象
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        boolean checkToken = checkToken(request);
        return joinPoint.proceed(); // 继续执行原方法
    }

    public boolean checkToken(HttpServletRequest request) {
        // step1判断token是否存在
        String token = request.getHeader("token");
        if (ObjectUtil.isNull(token) || token.isBlank()) {
            throw new RuntimeException("token不存在或已过期");
        } else {
            // 判断token是否存在
            SysUserToken checkTokenExist = sysUserTokenService.selectSysUserIdByUserToken(token);
            if(ObjectUtil.isNotNull(checkTokenExist)){
                // 判断token是否合法
                String s = JWTUtils.validateToken(token);
                if(ObjectUtil.isEmpty(s) && (-1 == DateUtil.compare(checkTokenExist.getExpireTime(), DateUtil.date()))){
                    throw new RuntimeException("token不存在或已过期");
                }else{
                    return true;
                }
            }else{
             throw new RuntimeException("token不存在或已过期");
            }
        }
    }
}